/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.jfonia.view.labels;

import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jfonia.connect5.basics.MutableValueNode;
import org.jfonia.connect5.basics.ValueNode;

/**
 *
 * @author Rik Bauwens
 */
public class Labels implements Iterable<Label>
{
        private Set<ILabelsObserver> observers = new LinkedHashSet<ILabelsObserver>();
        private List<Label> labels;
        private Map<ValueNode<Double>, Label> ratioToLabelMapper;

        public Labels()
        {
                //Linked list for performance reasons
                labels = new LinkedList<Label>();
                ratioToLabelMapper = new HashMap<ValueNode<Double>, Label>();
        }

        public void addLabel(Label label)
        {
                labels.add(label);
                ratioToLabelMapper.put(label.getRatioNode(), label);
                labelAdded(label);
        }

        public void removeLabel(Label label)
        {
                if(!labels.contains(label))
                        return;
                labels.remove(label);
                ratioToLabelMapper.remove(label.getRatioNode());
                labelRemoved(label);
        }

        public void removeLabel(MutableValueNode<Double> ratioNode)
        {
                removeLabel(ratioToLabelMapper.get(ratioNode));
        }

        public void clearLabels()
        {
                labels.clear();
                ratioToLabelMapper.clear();
        }

        public boolean isEmpty()
        {
                return labels.isEmpty();
        }

	public void addObserver(ILabelsObserver o)
	{
		if (!observers.contains(o))
			observers.add(o);
	}

	public boolean containsObserver(ILabelsObserver o)
	{
		return observers.contains(o);
	}

	public void removeObserver(ILabelsObserver o)
	{
		observers.remove(o);
	}

        private void labelAdded(Label label)
        {
		for (ILabelsObserver o: observers)
			o.labelAdded(label);
        }

        private void labelRemoved(Label label)
        {
		for (ILabelsObserver o: observers)
			o.labelRemoved(label);
        }

        public Iterator<Label> iterator()
        {
                return labels.iterator();
        }
}
